#include "../../../common/etcd.hpp"
#include "../../../common/channel.hpp"
#include <gflags/gflags.h>
#include <thread>
#include "main.pb.h"

DEFINE_bool(run_mode, false, "程序的运行模式,0-调试,1-发布");
DEFINE_string(log_file, "", "发布模式下,用于指定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下,用于指定日志的输出等级");

DEFINE_string(etcd_host, "http://127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监控根目录");
DEFINE_string(call_service, "/service/echo", "服务监控根目录");

int main(int argc, char *argv[])
{
    google::ParseCommandLineFlags(&argc, &argv, true);
    hdp::init_logger(FLAGS_run_mode, FLAGS_log_file, FLAGS_log_level);

    // 先构造Rpc信道管理对象
    std::shared_ptr<hdp::ServiceManager> sm = std::make_shared<hdp::ServiceManager>();
    sm->declared(FLAGS_call_service);

    std::function<void(std::string, std::string)> put_cb = std::bind(&hdp::ServiceManager::onServiceOnline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    std::function<void(std::string, std::string)> del_cb = std::bind(&hdp::ServiceManager::onServiceOffline, sm.get(), std::placeholders::_1, std::placeholders::_2);
    // 构造服务发现对象
    hdp::Discovery::ptr dclint = std::make_shared<hdp::Discovery>(FLAGS_etcd_host, FLAGS_base_service, put_cb, del_cb);

    for (;;)
    {
        // 通过RPC信道管理对象,获取提供Echo服务的信道
        hdp::ServiceChannel::ChannelPtr channel = sm->choose(FLAGS_call_service);
        if (channel == nullptr)
        {
            std::this_thread::sleep_for(std::chrono::seconds(1));
            // return -1;
            continue;
        }
        // 构造EchoService_Stub对象,用于进行rpc调用
        example::EchoService_Stub echo_stub(channel.get());
        // 进行Rpc调用
        example::EchoRequest req;
        req.set_message("Hello EchoService");

        brpc::Controller *cntl = new brpc::Controller();
        example::EchoResponse *resp = new example::EchoResponse();

        // 同步调用
        echo_stub.Echo(cntl, &req, resp, nullptr);
        if (cntl->Failed() == true)
        {
            std::cout << "发起RPC请求失败: " << cntl->ErrorText() << std::endl;
            delete cntl;
            delete resp;
            std::this_thread::sleep_for(std::chrono::seconds(1));
            continue;
        }

        std::cout << "收到响应: " << resp->message() << std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}